package com.yfqy.admin.exception;

import cn.hutool.json.JSONUtil;
import com.yfqy.admin.enums.ResponseEnum;
import com.yfqy.admin.domain.vo.common.ExceptionVO;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.List;

@RestControllerAdvice
public class GlobalExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @ExceptionHandler(value = Exception.class)
    public ExceptionVO exception(HttpServletRequest request, Exception e) {
        ExceptionVO exceptionVO = new ExceptionVO();
        exceptionVO.setCode(ResponseEnum.SYSTEM_ERROR.getCode());
        if (e instanceof AccessDeniedException) {
            exceptionVO.setMessage("用户权限不允许");
        } else {
            exceptionVO.setMessage("异常信息：" + e.getMessage());
        }
        exceptionVO.setPath(request.getRequestURI());
        exceptionVO.setMethod(request.getMethod());
        logger.error("GlobalExceptionHandler捕获全局Exception堆栈信息：", e);
        return exceptionVO;
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ExceptionVO methodArgumentNotValidException(HttpServletRequest request, MethodArgumentNotValidException e) {
        BindingResult result = e.getBindingResult();
        List<FieldError> fieldErrors = result.getFieldErrors();
        HashMap<String, String> errorFields = new HashMap<>();
        for (FieldError error : fieldErrors) {
            String fieldName = error.getField();
            errorFields.put(fieldName, error.getDefaultMessage());
        }
        ExceptionVO exceptionVO = new ExceptionVO();
        exceptionVO.setCode(ResponseEnum.BAD_REQUEST.getCode());
        exceptionVO.setMessage("异常信息：" + JSONUtil.toJsonStr(errorFields));
        exceptionVO.setPath(request.getRequestURI());
        exceptionVO.setMethod(request.getMethod());
        logger.error("GlobalExceptionHandler捕获全局MethodArgumentNotValidException堆栈信息：", e);
        return exceptionVO;
    }

    @ExceptionHandler(value = BaseException.class)
    public ExceptionVO baseException(HttpServletRequest request, BaseException e) {
        ExceptionVO exceptionVO = new ExceptionVO();
        exceptionVO.setCode(e.getCode());
        exceptionVO.setMessage("异常信息：" + e.getMessage());
        exceptionVO.setPath(request.getRequestURI());
        exceptionVO.setMethod(request.getMethod());
        logger.error("GlobalExceptionHandler捕获全局BaseException堆栈信息：", e);
        return exceptionVO;
    }

}
